package myCustom;

use strict;
use Plugins;
use Globals;
use Log qw(message warning error);
use AI;
use Misc;
use Utils;
use Settings;
use Commands;
use Network;
use Network::Send;

Plugins::register('myCustom', 'My Custom Plugin', \&on_unload);
my $hook1 = Plugins::addHooks(['AI_pre', \&AI_pre],['packet/area_spell', \&onAreaSpell, undef], , ['packet_privMsg',\&pmExtraCommand]);

sub on_unload {
	Plugins::delHooks($hook1);
}

my $healTime = time;
my $healTimeout = 5;
my $isAntiWarpOn = 0;
my $antiWarpID = 0;
my $antiWarpTime = time;
my $antiWarpTimeout = 10;
my $mapStuckTime = time;
my $mapStuckTimeMosk = time;
my $mapStuckTimeout = 60;
my $relogTime = time;
my $relogTimeout = 120;

sub AI_pre {
	if (percent_hp($char) < 80 && timeOut($healTime, $healTimeout)) {
		if ($playersList) {
			my $isSent = 0;
			foreach my $player (@{$playersList->getItems()}) {
				my ($name, $dist, $pos);
				$name = $player->name;
				if ($name eq "-AH01-" || $name eq "-AH02-" || $name eq "-AH03-" || $name eq "-AH04-" || $name eq "-AH05-" || $name eq "-AH06-" || $name eq "-AH07-" || $name eq "-AH08-" || $name eq "-AH09-") {
					$dist = distance($char->{pos_to}, $player->{pos_to});
					if ($dist < 6) {
						sendMessage($messageSender, "pm", "$config{'lilin_pass'} heal $char->{'hp'}", $name);
						$isSent = 1;
					}
				}
				elsif ($name eq "~MrsArchBishop" && $field->baseName() eq $config{'lockMap'}) {
					$dist = distance($char->{pos_to}, $player->{pos_to});
					if ($dist < 6) {
						sendMessage($messageSender, "pm", "$config{'lilin_pass'} heal $char->{'hp'}", $name);
						$isSent = 1;
					}
				}
			}
			if ($isSent eq 1) {
				$healTime = time;
			} else {
				if(timeOut($relogTime, $relogTimeout)) {
					if (AI::is("sitAuto")) {
						sendMessage($messageSender, "pm", "Ga bisa minta heal, di " . $field->baseName() . " " . $char->{pos_to}->{x} . ", " . $char->{pos_to}->{y} , "K-Seller");
						$relogTime = time;
						relog(1);
					}
				}
			}
			undef $isSent;
		} 
	}
	if ($isAntiWarpOn eq 1 && timeOut($antiWarpTime,$antiWarpTimeout)) {
		$isAntiWarpOn = 0;
		if ($currentChatRoom ne "") {
			$messageSender->sendChatRoomLeave();
		}
	}
	my $mapName = $field->baseName();
	my $lockMap = $config{'lockMap'};
	if (timeOut($mapStuckTime,$mapStuckTimeout)) {
		if ($lockMap eq "lhz_fild02") {
			if ($mapName ne "lighthalzen" && $mapName ne "lhz_fild01" && $mapName ne "lhz_fild02") {
				sendMessage($messageSender, "pm", "Aku di " . $mapName . " ". $char->{pos_to}->{x} . ", " . $char->{pos_to}->{y}, "K-Seller");
			}
		}
		elsif ($lockMap eq "ama_fild01") {
			if ($mapName ne "amatsu" && $mapName ne "ama_fild01") {
				sendMessage($messageSender, "pm", "Aku di " . $mapName . " ". $char->{pos_to}->{x} . ", " . $char->{pos_to}->{y}, "K-Seller");
			}
		}
		elsif ($lockMap eq "gef_fild06") {
			if ($mapName ne "geffen" && $mapName ne "gef_fild07" && $mapName ne "gef_fild06" && $mapName ne "gef_fild08") {
				sendMessage($messageSender, "pm", "Aku di " . $mapName . " ". $char->{pos_to}->{x} . ", " . $char->{pos_to}->{y}, "K-Seller");
			}
		}
		elsif ($lockMap eq "ve_fild07") {
			if ($mapName ne "veins" && $mapName ne "ve_fild07") {
				sendMessage($messageSender, "pm", "Aku di " . $mapName . " ". $char->{pos_to}->{x} . ", " . $char->{pos_to}->{y}, "K-Seller");
			}
		}
		elsif ($lockMap eq "moc_fild02") {
			if ($mapName ne "payon" && $mapName ne "pay_gld" && $mapName ne "moc_fild02") {
				sendMessage($messageSender, "pm", "Aku di " . $mapName . " ". $char->{pos_to}->{x} . ", " . $char->{pos_to}->{y}, "K-Seller");
			}
		}
		elsif ($mapName eq "mosk_fild02") {
			if (timeOut($mapStuckTimeMosk, $mapStuckTimeout)) {
				$mapStuckTimeMosk = time;
				sendMessage($messageSender, "pm", "Aku di moskovia " . $char->{pos_to}->{x} . ", " . $char->{pos_to}->{y}, "K-Vender");
				main::ai_route("mosk_fild02", 204, 53, attackOnRoute => 0, distFromGoal => 1);
			}
		}
		else {
			sendMessage($messageSender, "pm", "Aku di " . $mapName . " " . $char->{pos_to}->{x} . ", " . $char->{pos_to}->{y}, "K-Seller");
		}
		$mapStuckTime = time;
	}
}

sub onAreaSpell {
	my ($self, $args) = @_;

	# Area effect spell; including traps!
	my $ID = $args->{ID};
	my $sourceID = $args->{sourceID};
	my $x = $args->{x};
	my $y = $args->{y};
	my $type = $args->{type};
	my $fail = $args->{fail};

	if ($type == 0x81 || $type == 0x80) {
		my %line;
		$line{x} = abs($x - $char->{pos_to}->{x});
        $line{y} = abs($y - $char->{pos_to}->{y});
		my $dist = sqrt($line{x} ** 2 + $line{y} ** 2);
		my $mapName = $field->baseName();
		if ($dist < 5 && $mapName ne "mid_camp") {
			$isAntiWarpOn = 1;
			$antiWarpID = $ID;
			$antiWarpTime = time;
			sendMessage($messageSender, "pm", getActorName($sourceID) . " buka portal di " . $mapName, "K-Seller");
			return if ($currentChatRoom ne "");
			$messageSender->sendChatRoomCreate("capek kerja, duduk dulu ah", 1, 0, "12214");
			%createdChatRoom = ();
			$createdChatRoom{title} = "capek kerja, duduk dulu ah";
			$createdChatRoom{ownerID} = $accountID;
			$createdChatRoom{limit} = 1;
			$createdChatRoom{public} = 0;
			$createdChatRoom{num_users} = 1;
			$createdChatRoom{users}{$char->{name}} = 2;
		}
	}
}

sub pmExtraCommand {
	my ($self, $arg) = @_;
	my $sender = $arg->{privMsgUser};
	my $sentMsg = $arg->{privMsg};
	return if (!$overallAuth{$sender});
	my @args = parseArgs($arg->{privMsg});
	return if ($args[0] ne "info");
	if ($args[1] eq "item") {
		if ( $char->inventory->size() == 0) {
			sendMessage($messageSender, "pm", "Inventory is empty", $sender);
		}
		else {
			my @useable;
			my @equipment;
			my @uequipment;
			my @non_useable;
			my $tempCalc;
			my ($i, $display, $index, $sell);

			foreach my $item (@{$char->inventory->getItems()}) {
				if (($item->{type} == 3 ||
							$item->{type} == 6 ||
							$item->{type} == 10 ||
							$item->{type} == 16 ||
							$item->{type} == 17 ||
							$item->{type} == 19) && !$item->{equipped}) {
					push @non_useable, $item->{invIndex};
				} elsif ($item->{type} <= 2 ||
						$item->{type} == 18) {
					push @useable, $item->{invIndex};
				} else {
					my %eqp;
					$eqp{index} = $item->{index};
					$eqp{binID} = $item->{invIndex};
					$eqp{name} = $item->{name};
					$eqp{equipped} = ($item->{type} == 10 || $item->{type} == 16 || $item->{type} == 17 || $item->{type} == 19) ? $item->{amount} . " left" : $equipTypes_lut{$item->{equipped}};
					$eqp{type} = $itemTypes_lut{$item->{type}};
					$eqp{equipped} .= " ($item->{equipped})";
					$eqp{identified} = " -- " . "Not Identified" if !$item->{identified};
					if ($item->{equipped}) {
						push @equipment, \%eqp;
					} else {
						push @uequipment, \%eqp;
					}
				}
			}
			sendMessage($messageSender, "pm", "------------ Inventory List ------------", $sender);
			sendMessage($messageSender, "pm", "-- Equipment (Equipped) --", $sender);
			foreach my $item (@equipment) {
				$tempCalc = sprintf("%-3d  %s -- %s", $item->{binID}, $item->{name}, $item->{equipped});
				sendMessage($messageSender, "pm", $tempCalc , $sender);
			}
			sendMessage($messageSender, "pm", "-- Equipment (Not Equipped) --", $sender);
			foreach my $item (@uequipment) {
				$tempCalc = sprintf("%-3d  %s (%s) %s", $item->{binID}, $item->{name}, $item->{type}, $item->{identified});
				sendMessage($messageSender, "pm", $tempCalc, $sender);
			}

			sendMessage($messageSender, "pm", "-- Non Usable --", $sender);
			for ($i = 0; $i < @non_useable; $i++) {
				$index = $non_useable[$i];
				my $item = $char->inventory->get($index);
				$tempCalc = sprintf("%-3d  %s x %s", $index, $item->{name}, $item->{amount});
				sendMessage($messageSender, "pm", $tempCalc, $sender);
			}

			# Translation Comment: List of usable items
			sendMessage($messageSender, "pm", "-- Usable --", $sender);
			for ($i = 0; $i < @useable; $i++) {
				$index = $useable[$i];
				my $item = $char->inventory->get($index);
				$tempCalc = sprintf("%-3d  %s x %s", $index, $item->{name}, $item->{amount});
				sendMessage($messageSender, "pm", $tempCalc, $sender);
			}
			sendMessage($messageSender, "pm", "--------- End of Inventory List ---------", $sender);
		}
	} elsif ($args[1] eq "storage") {
		if (!$storage{opened} && !$storage{openedThisSession}) {
			sendMessage($messageSender, "pm", "Storage is not opened this session", $sender);
		} else {
			my @useable;
			my @equipment;
			my @non_useable;
			my $tempCalc;
		for (my $i = 0; $i < @storageID; $i++) {
			next if ($storageID[$i] eq "");
			my $item = $storage{$storageID[$i]};
			if ($item->{type} == 3 ||
					$item->{type} == 6 ||
					$item->{type} == 10 ||
					$item->{type} == 16 ||
					$item->{type} == 17 ||
					$item->{type} == 19) {
				push @non_useable, $item;
			} elsif ($item->{type} <= 2) {
				push @useable, $item;
			} else {
				my %eqp;
				$eqp{binID} = $i;
				$eqp{name} = $item->{name};
				$eqp{type} = $itemTypes_lut{$item->{type}};
				$eqp{identified} = " -- " . "Not Identified" if !$item->{identified};
				push @equipment, \%eqp;
			}
		}
		
		sendMessage($messageSender, "pm", "--------------- Storage List ---------------", $sender);
		sendMessage($messageSender, "pm", "-- Equipment --", $sender);
		foreach my $item (@equipment) {
			$tempCalc = sprintf("%-3d  %s (%s) %s\n", $item->{binID}, $item->{name}, $item->{type}, $item->{identified});
			sendMessage($messageSender, "pm", $tempCalc, $sender);
		}
		
		sendMessage($messageSender, "pm", "-- Non Usable --", $sender);
		for (my $i = 0; $i < @non_useable; $i++) {
			my $item = $non_useable[$i];
			my $binID = $item->{binID};
			$tempCalc = sprintf("%-3d  %s x %s",  $item->{binID}, $item->{name}, $item->{amount});
			sendMessage($messageSender, "pm", $tempCalc, $sender);
		}
		
		sendMessage($messageSender, "pm", "-- Usable --", $sender);
		for (my $i = 0; $i < @useable; $i++) {
			my $item = $useable[$i];
			my $binID = $item->{binID};
			my $display = $item->{name};
			$tempCalc = sprintf("%-3d  %s x %s",  $item->{binID}, $item->{name}, $item->{amount});
			sendMessage($messageSender, "pm", $tempCalc, $sender);
		}
		
		sendMessage($messageSender, "pm", "--------------------------------------------", $sender);
		$tempCalc = sprintf("Capacity: %d/%d", $storage{items}, $storage{items_max});
		sendMessage($messageSender, "pm", $tempCalc, $sender);
		sendMessage($messageSender, "pm", "------------- End Storage List -------------", $sender);
		}
	} elsif ($args[1] eq "exp") {
		if ($args[2] eq "") {
			my ($endTime_EXP, $w_sec);
			$endTime_EXP = time;
			$w_sec = int($endTime_EXP - $startTime_EXP);
			my ($bExpPerHour, $jExpPerHour, $percentBExp, $percentBExpPerHour, $bLvlUp, $percentJExp, $percentJExpPerHour, $jLvlUp, $zenyMade, $zenyPerHour);
			my $numDeaths = (defined $char->{deathCount})? $char->{deathCount} : 0;
			if ($w_sec > 0) {
				$zenyMade = $char->{zeny} - $startingzeny;
				$zenyPerHour = int($zenyMade / $w_sec * 3600);
				my $bExpPerHour = int($totalBaseExp / $w_sec * 3600);
				my $jExpPerHour = int($totalJobExp / $w_sec * 3600);
				if ($char->{exp_max} && $bExpPerHour){
					$percentBExp = " (".sprintf("%.2f",$totalBaseExp * 100 / $char->{exp_max})."%)";
					$percentBExpPerHour = " (".sprintf("%.2f",$bExpPerHour * 100 / $char->{exp_max})."%)";
					$bLvlUp = timeConvert(int(($char->{exp_max} - $char->{exp})/($bExpPerHour/3600)));
				}
				if ($char->{exp_job_max} && $jExpPerHour){
					$percentJExp  = " (".sprintf("%.2f",$totalJobExp * 100 / $char->{exp_job_max})."%)";
					$percentJExpPerHour = " (".sprintf("%.2f",$jExpPerHour * 100 / $char->{exp_job_max})."%)";
					$jLvlUp = timeConvert(int(($char->{'exp_job_max'} - $char->{exp_job})/($jExpPerHour/3600)));
				}
			}
			sendMessage($messageSender, "pm", "Botting Time : " . timeConvert($w_sec), $sender);
			sendMessage($messageSender, "pm", "BaseExp      : " . formatNumber($totalBaseExp) . $percentBExp, $sender);
			sendMessage($messageSender, "pm", "JobExp       : " . formatNumber($totalJobExp) . $percentJExp, $sender);
			sendMessage($messageSender, "pm", "BaseExp/Hour : " . formatNumber($bExpPerHour) . $percentBExpPerHour, $sender);
			sendMessage($messageSender, "pm", "JobExp/Hour  : " . formatNumber($jExpPerHour) . $percentJExpPerHour, $sender);
			sendMessage($messageSender, "pm", "Zeny Made    : " . formatNumber($zenyMade), $sender);
			sendMessage($messageSender, "pm", "Zeny per Hour: " . formatNumber($zenyPerHour), $sender);
			sendMessage($messageSender, "pm", "Base Levelup Time Estimation : " . $bLvlUp, $sender);
			sendMessage($messageSender, "pm", "Job Levelup Time Estimation : " . $jLvlUp, $sender);
			sendMessage($messageSender, "pm", "Death : " . $numDeaths, $sender);
		} elsif ($args[2] eq "monster") {
			my $numKilledMonsters = 0;
			my $killedMonsters;
			sendMessage($messageSender, "pm", "No  Name                      Count", $sender);
			for (my $i = 0; $i < @monsters_Killed; $i++) {
				next if ($monsters_Killed[$i] eq "");
				$killedMonsters = swrite(
					"@<< @<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<",
					[$i, $monsters_Killed[$i]{name}, $monsters_Killed[$i]{count}]);
				$killedMonsters = substr($killedMonsters, 0, length($killedMonsters) - 1);
				$numKilledMonsters += $monsters_Killed[$i]{count};
				sendMessage($messageSender, "pm", $killedMonsters, $sender);
			}
			sendMessage($messageSender, "pm", "Total number of killed monsters: " . $numKilledMonsters, $sender);

		} elsif ($args[2] eq "item") {
			sendMessage($messageSender, "pm", "Name                                    Count", $sender);
			my $gotItems;
			for my $item (sort keys %itemChange) {
				next unless $itemChange{$item};
				$gotItems = sprintf("%-40s %5d", $item, $itemChange{$item});
				sendMessage($messageSender, "pm", $gotItems, $sender);
			}
			
		} else {
			sendMessage($messageSender, "pm", "No Data", $sender);
		}
	}
}

1;